"""
全局参数


"""

from contextvars import ContextVar

from starlette.requests import Request

from models.other.ctx import RequestContext
from models.po import UserPO
from my_typing import *
from utils.data_utils.special import ObjectIdStr

request_ctx: ContextVar[DictOrNone] = ContextVar("request_context", default=None)
"""
请求上下文

在 FastAPI 这样的异步框架中，使用 `threading.Thread` 确实可能会出现并发问题。原因是：
    - FastAPI 使用 asyncio 处理请求，一个线程可能同时处理多个请求
    - 线程级别的上下文在异步环境中不安全

更好的解决方案是使用 ContextVar
"""


def get_request_context() -> dict:
    """ 获取当前请求上下文 """

    return request_ctx.get() or {}


def update_request_context(updates: dict) -> None:
    """
    更新请求上下文

    在 ContextVar 中，每次调用 set() 都会完全覆盖之前的值，而不是更新
    如果需要实现更新，需要先把原先的内容取出来，再更新

    Args:
        updates: 需要更新的字典
    """

    current_ctx: dict = get_request_context()
    current_ctx.update(updates)
    request_ctx.set(current_ctx)


def update_request_scope(
    request: Request,
    updates: dict,
) -> None:
    """ 更新请求 scope """

    request.scope.update(updates)


def get_ctx() -> RequestContext:
    """ 获取当前线程的请求上下文 """

    current_ctx: dict = get_request_context()

    return RequestContext(**current_ctx)


def get_current_user() -> UserPO | None:
    """ 获取当前线程的用户 """

    return get_ctx().user


def get_user_id() -> ObjectIdStr | None:
    """ 获取当前线程的用户 ID """

    return get_ctx().user_id
